/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package service.reportCenter.tankScheduling;

import com.openbrew.openbrewrf.Brews;
import com.openbrew.openbrewrf.Fv;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import service.enumerations.MovementState;

/**
 *
 * @author dchapman
 */
@Stateless
@Path("com.openbrew.openbrewrf.tankschedulereport")
public class TankScheduleReportREST {
    @PersistenceContext(unitName = "com.openBrew_openBrewRF_war_1.0PU")
    private EntityManager em;
    
    private final int GANTTPRIMARY = 0;
    private final int GANTTSECONDARY = 1;
    private final int GANTTCOND = 2;
    private final int REAL_PRIMARY = 3;
    private final int REAL_SECOND = 4;
    private final int REAL_COND = 5;
    private final int REAL_GANTT_PRIME = 6;
    private final int REAL_GANTT_SECOND = 7;
    private final int REAL_GENTT_COND = 8;
    
    List<Fv> vessels = new ArrayList<Fv>();
    List<Brews> brews = new ArrayList<Brews>();
    
    Date today = new Date();
    
    private void loadVessels(){
        vessels.removeAll(vessels);
        vessels = getEntityManager().createNamedQuery("Fv.findAll", Fv.class).getResultList();
    }
    
    private void loadBrews(){
        brews.removeAll(brews);
        brews = getEntityManager().createNamedQuery("Brews.findInProcess", Brews.class).getResultList();
    }
    
    private List<TankSchedule> createTankSchedules(){
        //Creates a blank tank schedule.
        loadVessels();
        int idx = 0;
        List<TankSchedule> tankSchedules = new ArrayList<TankSchedule>();
        for(Fv vessel : vessels){
            TankSchedule newTS = new TankSchedule();
            newTS.setIndex(idx);
            newTS.setTankDesg(vessel.getFVDesg());
            newTS.setTankID(vessel.getFvid());
            newTS.setSecondaryTank(!vessel.getFvprm());
            tankSchedules.add(newTS);
            idx++;
        }
        return tankSchedules;
    }
    
    private TankBrews getTankBrew(final Brews brew, int type){
        TankBrews tb = new TankBrews();
        tb.setBrewID(brew.getBid());
        tb.setBrewName(brew.getBrewDescription());
        tb.setDoubleBooked(false);
        tb.setColor(brew.getGanttColor());
        if(type == GANTTPRIMARY){
            tb.setDateIn(brew.getGanttStart());
            tb.setDateOut(brew.getGanttSecond());
        } else if(type == GANTTSECONDARY){
            tb.setDateIn(brew.getGanttSecond());
            tb.setDateOut(brew.getGanttCond());
        } else if(type == GANTTCOND){
            tb.setDateIn(brew.getGanttCond());
            tb.setDateOut(brew.getGanttStop());
        } else if(type == REAL_GANTT_PRIME){
            tb.setDateIn(brew.getBDate());
            tb.setDateOut(brew.getGanttSecond());
        } else if(type == REAL_GANTT_SECOND){
            tb.setDateIn(brew.getSFDate01());
            tb.setDateOut(brew.getGanttCond());
        } else if(type == REAL_GENTT_COND){
            tb.setDateIn(brew.getCTDate());
            if(brew.getGanttStop().before(brew.getCTDate())){
                tb.setDateOut(today);
            } else {
                tb.setDateOut(brew.getGanttStop());
            }
        } else if(type == REAL_PRIMARY){
            tb.setDateIn(brew.getBDate());
            tb.setDateOut(brew.getSFDate01());
        } else if(type == REAL_SECOND){
            tb.setDateIn(brew.getSFDate01());
            tb.setDateOut(brew.getCTDate());
        } else if(type == REAL_COND){
            tb.setDateIn(brew.getCTDate());
            tb.setDateOut(brew.getPDate());
        }
        return tb;
    }
    
    @GET
    @Produces(MediaType.APPLICATION_XML)
    public List<TankSchedule> find() {
        loadBrews();
        List<TankSchedule> tankSchedules = createTankSchedules();
        
        for(TankSchedule ts : tankSchedules){
            final int vessel = ts.getTankID();
            for(Brews brew : brews){
                //Throw away any brews that are finished.
                if(brew.getBState() == MovementState.BREWING.getState()){
                    //Use only predictive dates.
                    if(brew.getGanttPID() == vessel){
                        ts.addTankBrew(getTankBrew(brew, GANTTPRIMARY));
                    }
                    if(brew.getGanttSID() == vessel){
                        ts.addTankBrew(getTankBrew(brew, GANTTSECONDARY));
                    }
                    if(brew.getGanttCID() == vessel){
                        ts.addTankBrew(getTankBrew(brew, GANTTCOND));
                    }
                } else if (brew.getBState()==MovementState.FERMENTING.getState()){
                    //Use actual primary, estimated secondary, conditioning, and packaging..
                    if(brew.getPfvid() == vessel){
                        ts.addTankBrew(getTankBrew(brew, REAL_GANTT_PRIME));
                    }
                    if(brew.getGanttSID() == vessel){
                        ts.addTankBrew(getTankBrew(brew, GANTTSECONDARY));
                    }
                    if(brew.getGanttCID() == vessel){
                        ts.addTankBrew(getTankBrew(brew, GANTTCOND));
                    }
                } else if (brew.getBState()==MovementState.LAGERING.getState()){
                    //use actual primary and secondary, use estimated conditioning and packaging..
                    if(brew.getPfvid() == vessel){
                        ts.addTankBrew(getTankBrew(brew, REAL_PRIMARY));
                    }
                    if(brew.getSfvid() == vessel){
                        ts.addTankBrew(getTankBrew(brew, REAL_GANTT_SECOND));
                    }
                    if(brew.getGanttCID() == vessel){
                        ts.addTankBrew(getTankBrew(brew, GANTTCOND));
                    }
                } else if (brew.getBState()==MovementState.CONDITIONING.getState()){
                    //use actual primary, secondary, and conditioning, estimated packaging.
                    if(brew.getPfvid() == vessel){
                        ts.addTankBrew(getTankBrew(brew, REAL_PRIMARY));
                    }
                    if(brew.getSfvid() == vessel){
                        ts.addTankBrew(getTankBrew(brew, REAL_SECOND));
                    }
                    if(brew.getCvid() == vessel){
                        ts.addTankBrew(getTankBrew(brew, REAL_GENTT_COND));
                    }
                } else if (brew.getBState()>=20){
                    //use actual dates for everything.
                    if(brew.getPfvid() == vessel){
                        ts.addTankBrew(getTankBrew(brew, REAL_PRIMARY));
                    }
                    if(brew.getSfvid() == vessel){
                        ts.addTankBrew(getTankBrew(brew, REAL_SECOND));
                    }
                    if(brew.getCvid() == vessel){
                        ts.addTankBrew(getTankBrew(brew, REAL_COND));
                    }
                }
            }
        }
        
        for(TankSchedule ts : tankSchedules){
            if(ts.getBrews()!=null){
                Collections.sort(ts.getBrews(), new Comparator<TankBrews>() {
                    @Override
                    public int compare(TankBrews t1, TankBrews t2) {
                        return t1.getDateIn().compareTo(t2.getDateIn());
                    }
                });
            }
        }
        
        return tankSchedules;
    }
    
    protected EntityManager getEntityManager() {
        return em;
    }
}
